/**   
 * Copyright © 2019 eSunny Info. Tech Ltd. All rights reserved.
 * 
 * 功能描述：
 * @Package: com.seccloud.tencentcloudapi.ext 
 * @author: Yannis   
 * @date: 2019年9月9日 上午10:43:32 
 */
package com.tce;

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import javax.xml.bind.DatatypeConverter;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;

import com.alibaba.fastjson.JSONObject;

public class TceUtils {
	public static final String SECRET_ID = "AKIDMYpwoWfHNFwBFAlU1rlGnAKAoGUS2cuw";
	public static final String SECRET_KEY = "iHyUmphkfXAJFenfKjuX3A7sSM4aHnge";

	public static String sign(String stringToSign, String key, String method) throws Exception {
		Mac mac = Mac.getInstance(method);
		SecretKeySpec secretKeySpec = new SecretKeySpec(key.getBytes("UTF-8"), mac.getAlgorithm());
		mac.init(secretKeySpec);
		byte[] hash = mac.doFinal(stringToSign.getBytes("UTF-8"));
		return DatatypeConverter.printBase64Binary(hash);
	}
	

	public static String getStringToSign(TreeMap<String, Object> params, String urlToSign) {
		StringBuilder s2s = new StringBuilder(urlToSign + "/?");
		// 签名时要求对参数进行字典排序，此处用TreeMap保证顺序
		for (String k : params.keySet()) {
			if(null == params.get(k) ) {
				continue;
			}
			s2s.append(k).append("=").append(params.get(k).toString()).append("&");
		}
		return s2s.toString().substring(0, s2s.length() - 1);
	}

	public static String getUrl(TreeMap<String, Object> params, String reqUrl) throws UnsupportedEncodingException {
		StringBuilder url = new StringBuilder(reqUrl + "/?");
		url.append(getParamForBody(params));
		return url.toString();
	}
	
	public static List<NameValuePair> getParamListForBody(TreeMap<String, Object> params) throws UnsupportedEncodingException {
		List<NameValuePair> paramList = new ArrayList<NameValuePair>();
		// 实际请求的url中对参数顺序没有要求
		for (String k : params.keySet()) {
			if(null == params.get(k)) {
				continue;
			}
			// 需要对请求串进行urlencode，由于key都是英文字母，故此处仅对其value进行urlencode
			paramList.add(new BasicNameValuePair(k, params.get(k).toString()));
		}
		return paramList;
	}

	public static String getParamForBody(TreeMap<String, Object> params) throws UnsupportedEncodingException {
		StringBuilder paramSb = new StringBuilder();
		// 实际请求的url中对参数顺序没有要求
		for (String k : params.keySet()) {
			// 需要对请求串进行urlencode，由于key都是英文字母，故此处仅对其value进行urlencode
			paramSb.append(k).append("=").append(URLEncoder.encode(params.get(k).toString(), "UTF-8")).append("&");
		}
		return paramSb.toString().substring(0, paramSb.length() - 1);
	}
	
    public static TreeMap<String, Object> fillParam( String actionName, String region, String version, String methodUrl, JSONObject bodyJson) throws Exception {
    	TreeMap<String, Object> params = new TreeMap<String, Object>(); // TreeMap可以自动排序
        // 实际调用时应当使用随机数，例如：params.put("Nonce", new Random().nextInt(java.lang.Integer.MAX_VALUE));
        params.put("Nonce", new Random().nextInt(java.lang.Integer.MAX_VALUE)); // 公共参数
        // 实际调用时应当使用系统当前时间，例如：   params.put("Timestamp", System.currentTimeMillis() / 1000);
        params.put("Timestamp", System.currentTimeMillis() / 1000); // 公共参数
        params.put("SecretId", SECRET_ID); // 公共参数
        params.put("Action", actionName); // 公共参数
        if(null != version) {
        	params.put("Version", version); // 公共参数
        }
        params.put("Region", region); // 公共参数
        params.put("SignatureMethod", "HmacSHA1"); // 公共参数

        if(null != bodyJson) {
        	params.putAll(bodyJson);
        }
        String stringToSign = getStringToSign(params, methodUrl);
        String signStr = sign(stringToSign, SECRET_KEY, "HmacSHA1");
		params.put("Signature", signStr); 
        return params;
    }
	
	public static TreeMap<String, String> fillHttpHead(String reqUrl) {
		TreeMap<String, String> headers = new TreeMap<String, String>();
		headers.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
		headers.put("Host", reqUrl);
		return headers;
	}
	

	public static TreeMap<String, Object> fillTsfParam(JSONObject body, String actionName, String region, String reqUrl, String method, String version)
			throws Exception {
		String methodUrl = method + reqUrl;
		TreeMap<String, Object> paramTree = fillParam(actionName, region, version, methodUrl, body);
		return paramTree;
	}
}
